home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 April: Mac OS SDK / Dev.CD Apr 98 SDK1.toast / Development Kits (Disc 1) / QuickDraw 3D / Samples / SampleCode / Group Dumper ƒ / DumpGroup.c next >
Encoding:
C/C++ Source or Header  |  1997-08-14  |  8.4 KB  |  374 lines  |  [TEXT/CWIE]

  1. /*
  2.  * DumpGroup.c
  3.  *
  4.  * This code lets you select a QuickDraw 3D 3DMF file (via
  5.  * the Standard Get File dialog) which is parsed to find all
  6.  * objects in the metafile.  The object class names of these
  7.  * objects are printed in a SIOUX window indented according
  8.  * to their nested level in the group hierarchy. When an
  9.  * attribute set is encountered all contained attributes
  10.  * are printed after this object type.
  11.  *
  12.  * Change History:
  13.  * 
  14.  *    12/01/96    Nick Thompson - Created initial version.
  15.  *    01/21/97    Robert Dierkes - Added nesting level at beginning of each
  16.  *                printed line and the parsing of attribute sets.
  17.  * 
  18.  * ©1997 Apple computer Inc., All Rights Reserved
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23.  
  24. #include <CodeFragments.h>
  25. #include <Dialogs.h>
  26. #include <Fonts.h>
  27. #include <Memory.h>
  28. #include <QuickDraw.h>
  29. #include <StandardFile.h>
  30. #include <Windows.h>
  31.  
  32. #include "QD3D.h"
  33. #include "QD3DGroup.h"
  34. #include "QD3DIO.h"
  35. #include "QD3DStorage.h"
  36.  
  37.  
  38. /* Local prototypes */
  39. static void InitToolbox(void) ;
  40. void PrintGroupElementsAndRecurse( TQ3GroupObject theGroup, unsigned long depth );
  41. TQ3Status PrintAttributeSetType(TQ3AttributeSet objectType);
  42.  
  43.  
  44.  
  45. /* initialize the Mac toolbox */
  46. static void InitToolbox(void)
  47. {
  48.  
  49.     MaxApplZone() ;
  50.     MoreMasters() ; MoreMasters() ; MoreMasters() ; 
  51.     
  52.     InitGraf( &qd.thePort );
  53.     InitFonts();
  54.     InitWindows();
  55.  
  56.     FlushEvents( everyEvent, 0 ) ;
  57.  
  58.     InitCursor();
  59. }
  60.  
  61. static TQ3FileObject MyNewFileObject( FSSpec *myFSSpec )
  62. {
  63.     TQ3FileObject        myFileObj;
  64.     TQ3StorageObject    myStorageObj;
  65.     OSType                myFileType;
  66.     FInfo                fndrInfo ;
  67.  
  68.     /*
  69.      * we assume the FSSpec passed in was valid, get the file information
  70.      * we need to know the file type, this routine may get called by an appleEvent
  71.      * handler, so we can't assume a type, we need to get it from the fsspec.
  72.      */
  73.     
  74.     FSpGetFInfo( myFSSpec, &fndrInfo ) ;
  75.     
  76.     /* pull out the file type */
  77.     
  78.     myFileType = fndrInfo.fdType ;
  79.     
  80.     /* Create new storage object and new file object */
  81.     if(((myStorageObj = Q3FSSpecStorage_New( myFSSpec )) == NULL) 
  82.         || ((myFileObj = Q3File_New()) == NULL)) 
  83.     {
  84.         if (myStorageObj != NULL) 
  85.             Q3Object_Dispose(myStorageObj);
  86.         return(NULL);
  87.     }
  88.  
  89.     /* Set the storage for the file object */
  90.     Q3File_SetStorage(myFileObj, myStorageObj);
  91.     Q3Object_Dispose(myStorageObj);
  92.  
  93.     return (myFileObj);
  94. }
  95.  
  96.  
  97. static TQ3Status MyReadObjectsFromFileIntoGroup( TQ3FileObject theFile,TQ3GroupObject myGroup)
  98. {    
  99.     if(theFile != NULL) {
  100.     
  101.         TQ3Object            myTempObj ;
  102.         TQ3Boolean            isEOF ;
  103.                 
  104.     
  105.         /* read all objects from the file into the group */
  106.         do {
  107.         
  108.             myTempObj = Q3File_ReadObject( theFile );
  109.             
  110.             if( myTempObj != NULL ) {
  111.             
  112.                 if( !Q3Object_IsType( myTempObj, kQ3SharedTypeViewHints ) )
  113.                 {
  114.                     Q3Group_AddObject( myGroup, myTempObj ) ;
  115.                 }
  116.                 Q3Object_Dispose( myTempObj ) ;
  117.                 
  118.             }
  119.             
  120.             /* check to see if we reached the end of file yet */
  121.             isEOF = Q3File_IsEndOfFile( theFile );
  122.             
  123.         } while (isEOF == kQ3False);    
  124.     }
  125.     
  126.     if( myGroup != NULL )
  127.         return kQ3Success ;
  128.     else
  129.         return kQ3Failure ;
  130. }
  131.  
  132.  
  133. static TQ3GroupObject MyNewModelFromFile(FSSpec *theFileSpec)
  134. {
  135.     TQ3GroupObject        myGroup = NULL ;
  136.     TQ3Boolean            isText = kQ3False ;
  137.     TQ3FileMode            myFileMode = 0;
  138.     TQ3FileObject        theFile;
  139.     
  140.     /*    Create a group for the complete model. */
  141.     if ((myGroup = Q3Group_New()) == NULL )
  142.         return NULL;
  143.  
  144.     theFile = MyNewFileObject( theFileSpec ) ;
  145.     
  146.     // Open the file object
  147.     if( Q3File_OpenRead( theFile, &myFileMode ) != kQ3Success)
  148.         return  NULL ;
  149.  
  150.     if( MyReadObjectsFromFileIntoGroup( theFile, myGroup ) == 0)
  151.         DebugStr("\pMetafile data read is null") ;
  152.     
  153.     Q3File_Close(theFile);            // close and dispose of the file object
  154.     Q3Object_Dispose(theFile);
  155.     
  156.     return myGroup ;
  157. }
  158.  
  159. /* get an FSSpec for a metafile */
  160. static Boolean MetafileFileSpecify( FSSpec *theFile )
  161. {
  162.     StandardFileReply    theSFReply ;
  163.     SFTypeList            myTypes = { '3DMF' } ;
  164.     const short            numTypes = 1 ;
  165.         
  166.     /* Get the file name to open */
  167.     StandardGetFile( nil, numTypes, myTypes, &theSFReply ) ;
  168.     
  169.     if( theSFReply.sfGood )
  170.         *theFile = theSFReply.sfFile ;
  171.     
  172.     /* did the user cancel? */
  173.     return theSFReply.sfGood ;
  174.     
  175. }
  176.  
  177. /* the guts... :) */
  178. void PrintGroupElementsAndRecurse( TQ3GroupObject theGroup, unsigned long depth )
  179. {
  180.  
  181.     TQ3GroupPosition            thePosition ;
  182.     TQ3Object                    theObjectAtPosition ;
  183.     TQ3Status                    theStatus ;
  184.  
  185.     TQ3Object                    thisObject ;
  186.     TQ3ObjectType                thisObjectType ;
  187.     TQ3ObjectClassNameString     objectClassString ;
  188.     
  189.     unsigned long                i ;
  190.     unsigned long                numberOfObjects ;
  191.     
  192.     /* sanity checks, and totals... */
  193.     if( depth < 1 ) 
  194.         depth = 1 ;    /* we must always be called with a depth of at least 1 */
  195.     
  196.     if ( Q3Object_IsType( theGroup, kQ3ShapeTypeGroup) )
  197.     {
  198.         /* print the group name here */
  199.         thisObjectType = Q3Object_GetLeafType ( theGroup ) ;
  200.         
  201.         Q3ObjectHierarchy_GetStringFromType( thisObjectType,  objectClassString) ;
  202.         Q3Group_CountObjects( theGroup, &numberOfObjects ) ;
  203.         
  204.         /* really this group is at the level before this, so subtract 1 from the total */
  205.         printf("%4u  ", (depth - 1)) ;
  206.         for( i = 0; i < (depth - 1); i++ )
  207.             printf("  ") ;
  208.             
  209.         printf( "%s (contains %u objects)\n",    objectClassString,  numberOfObjects) ;    
  210.     }
  211.     else
  212.     {
  213.         printf( "PrintGroupElementsAndRecurse called in error, theGroup ain't a group") ;
  214.         return ;
  215.     }
  216.         
  217.  
  218.     /* get the first object from the group and iterate through */
  219.     theStatus = Q3Group_GetFirstPosition ( theGroup, &thePosition ) ;
  220.     
  221.     
  222.     while( thePosition != NULL && theStatus == kQ3Success )
  223.     {
  224.     
  225.         theStatus = Q3Group_GetPositionObject ( theGroup, thePosition, &thisObject ) ;
  226.         
  227.         if(theStatus == kQ3Failure )
  228.         {
  229.             printf("GetPositionObject failed, Aborting") ;
  230.             return ;
  231.         }
  232.         
  233.         
  234.         if ( Q3Object_IsType( thisObject, kQ3ShapeTypeGroup) )
  235.         {
  236.             PrintGroupElementsAndRecurse( thisObject, depth + 1 ) ;
  237.         }
  238.         else
  239.         {
  240.             thisObjectType = Q3Object_GetLeafType ( thisObject ) ;
  241.             
  242.             Q3ObjectHierarchy_GetStringFromType( thisObjectType,  objectClassString) ;
  243.             
  244.             printf("%4u  ", depth) ;
  245.             for( i = 0; i < depth; i++ )
  246.                 printf("  ") ;
  247.                 
  248.             printf( "%s",    objectClassString ) ;    
  249.  
  250.             if (thisObjectType == kQ3SetTypeAttribute) {
  251.                 PrintAttributeSetType(thisObject);
  252.             }
  253.                 
  254.             printf( "\n" ) ;    
  255.         }
  256.             
  257.         Q3Object_Dispose( thisObject ) ;
  258.         
  259.         /* finally get the next object in the group */
  260.         theStatus = Q3Group_GetNextPosition(theGroup, &thePosition) ;
  261.     }
  262.     
  263. }
  264.  
  265. TQ3Status PrintAttributeSetType(TQ3Object object)
  266. {
  267.     TQ3AttributeType    attrType;
  268.     TQ3AttributeType    attributeTypes[] = {
  269.                             kQ3AttributeTypeNone,
  270.                             kQ3AttributeTypeSurfaceUV,
  271.                             kQ3AttributeTypeShadingUV,
  272.                             kQ3AttributeTypeNormal,
  273.                             kQ3AttributeTypeAmbientCoefficient,
  274.                             kQ3AttributeTypeDiffuseColor,
  275.                             kQ3AttributeTypeSpecularColor,
  276.                             kQ3AttributeTypeSpecularControl,
  277.                             kQ3AttributeTypeTransparencyColor,
  278.                             kQ3AttributeTypeSurfaceTangent,
  279.                             kQ3AttributeTypeHighlightState,
  280.                             kQ3AttributeTypeSurfaceShader
  281.                         };
  282.     char                *attributeTypeNames[] = {
  283.                             "None",
  284.                             "SurfaceUV",
  285.                             "ShadingUV",
  286.                             "Normal",
  287.                             "AmbientCoefficient",
  288.                             "DiffuseColor",
  289.                             "SpecularColor",
  290.                             "SpecularControl",
  291.                             "TransparencyColor",
  292.                             "SurfaceTangent",
  293.                             "HighlightState",
  294.                             "SurfaceShader"
  295.                         };
  296.     unsigned long        i, total, count;
  297.     TQ3Status            status;
  298.  
  299.     if (Q3Object_IsType(object, kQ3SetTypeAttribute) == kQ3False) {
  300.         return kQ3Failure;
  301.     }
  302.  
  303.     count = 0;
  304.     total = sizeof(attributeTypes) / sizeof(TQ3AttributeType);
  305.     attrType = kQ3AttributeTypeNone;
  306.  
  307.     while (1) {
  308.         status = Q3AttributeSet_GetNextAttributeType(object, &attrType);
  309.         if (status == kQ3Failure) {
  310.             break;
  311.         }
  312.  
  313.         if (attrType == kQ3AttributeTypeNone) {
  314.             break;
  315.         }
  316.  
  317.         printf((count == 0) ? "  [" : ", ");
  318.  
  319.         for (i = 0; i < total; i++) {
  320.             if (attrType == attributeTypes[i]) {
  321.                 break;
  322.             }
  323.         }
  324.  
  325.         if (i < total) {
  326.             printf("%s", attributeTypeNames[i]);
  327.         }
  328.         else {
  329.             printf("Custom(%u)", attrType);
  330.         }
  331.  
  332.         count++;
  333.     }
  334.  
  335.     if (count) {
  336.         printf("]");
  337.     }
  338.     else {
  339.         printf("  [None]", attrType);
  340.     }
  341.  
  342.     return status;
  343. }
  344.  
  345.  
  346. #ifdef STADALONE_PROGRAM_TO_DUMP_A_GROUP
  347. /* entry point */
  348. void main(void)
  349. {
  350.     TQ3Status     myStatus ;
  351.     
  352.     InitToolbox() ;
  353.     if( (long)Q3Initialize != kUnresolvedCFragSymbolAddress )
  354.     {
  355.         if((myStatus = Q3Initialize()) == kQ3Success)
  356.         {
  357.             FSSpec        theFileSpec ;
  358.             
  359.             /* get a metafile */
  360.             if( MetafileFileSpecify( &theFileSpec ))
  361.             {
  362.                 TQ3GroupObject         theGroup ;
  363.                 
  364.                 if((theGroup = MyNewModelFromFile(&theFileSpec )) != NULL )
  365.                     PrintGroupElementsAndRecurse( theGroup, 0L );
  366.                     
  367.                 Q3Object_Dispose( theGroup ) ;
  368.             }
  369.             Q3Exit() ;
  370.         } 
  371.     }
  372. }
  373. #endif
  374.